﻿using System;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;

namespace Admin.CYT369.Com.DAL.Services
{
    public class OrganizationService : Admin.CYT369.Com.DAL.DbContexts.BaseService<OrganizationService>
    {
        public OrganizationService() { }

        #region Organization
        public IQueryable<Admin.CYT369.Com.DAL.Domains.Organization> GetOrganizations(int? parentId = null)
        {
            var query = this.Get<Admin.CYT369.Com.DAL.Domains.Organization>();
            if (parentId.HasValue)
            {
                query = query.Where(c => c.ParentID == parentId.Value);
            }

            return query.OrderBy(c => c.Id);
        }

        public Admin.CYT369.Com.DAL.Domains.Organization GetOrganizationByID(int id)
        {
            return this.GetOne<Admin.CYT369.Com.DAL.Domains.Organization>(c => c.Id == id);
        }

        public bool SaveOrganization(Admin.CYT369.Com.DAL.Domains.Organization organization)
        {
            if (organization.Id > 0)
            {
                return this.Save<Admin.CYT369.Com.DAL.Domains.Organization>(organization, c => c.Id == organization.Id);
            }
            else
            {
                return this.Save<Admin.CYT369.Com.DAL.Domains.Organization>(organization);
            }
        }

        public bool DeleteOrganization(int id)
        {
            using (var db = this.Ctx)
            {
                var list = new List<Admin.CYT369.Com.DAL.Domains.Organization>();
                if (db.Set<Admin.CYT369.Com.DAL.Domains.Organization>().Where(c => c.ParentID == id).Count() > 0) {
                    throw new Admin.CYT369.Com.Utility.Exceptions.DataExistException("任存在下级组织机构数据，不能删除当前数据");
                }

                if (db.Set<Admin.CYT369.Com.DAL.Domains.Department>().Where(c => c.OrgID == id).Count() > 0)
                {
                    throw new Admin.CYT369.Com.Utility.Exceptions.DataExistException("该组织机构存在相关的部门数据，不能删除当前组织机构信息");
                }

                if (db.Set<Admin.CYT369.Com.DAL.Domains.Position>().Where(c => c.OrgID == id).Count() > 0)
                {
                    throw new Admin.CYT369.Com.Utility.Exceptions.DataExistException("该组织机构存在相关的职位数据，不能删除当前组织机构信息");
                }

                var item = db.Set<Admin.CYT369.Com.DAL.Domains.Organization>().Where(c => c.Id == id).FirstOrDefault();
                if (item != null)
                {
                    db.Set<Admin.CYT369.Com.DAL.Domains.Organization>().Remove(item);
                    db.SaveChanges();

                    return true;
                }
            }

            return false;
        }
        #endregion

        #region Department
        public IQueryable<Admin.CYT369.Com.DAL.Domains.Department> GetDepartments(
            int page, int rows, ref int total,
            int? orgId = null, int ? parentId = null, bool? enable = null, string departmentName = null)
        {
            var query = this.Get<Admin.CYT369.Com.DAL.Domains.Department>();

            if (orgId.HasValue)
            {
                query = query.Where(c => c.OrgID == orgId.Value);
            }

            if (parentId.HasValue)
            {
                query = query.Where(c => c.ParentID == parentId.Value);
            }

            if (enable.HasValue)
            {
                query = query.Where(c => c.Enable == enable.Value);
            }

            if (!string.IsNullOrEmpty(departmentName))
            {
                query = query.Where(c => c.FullName.Contains(departmentName));
            }

            //return query.OrderBy(c => c.Id);
            return this.Pagination(page, rows, ref total, query, c => c.Id);
        }


        public IQueryable<Admin.CYT369.Com.DAL.Domains.Department> GetDepartments(int? orgId = null, int? parentId = null, bool? enable = null)
        {
            var query = this.Get<Admin.CYT369.Com.DAL.Domains.Department>();

            if (orgId.HasValue)
            {
                query = query.Where(c => c.OrgID == orgId.Value);
            }

            if (parentId.HasValue)
            {
                query = query.Where(c => c.ParentID == parentId.Value);
            }

            if (enable.HasValue)
            {
                query = query.Where(c => c.Enable == enable.Value);
            }

            return query.OrderBy(c => c.Id);
        }

        public Admin.CYT369.Com.DAL.Domains.Department GetDepartmentByCode(string code)
        {
            return this.GetOne<Admin.CYT369.Com.DAL.Domains.Department>(c => c.Code == code);
        }

        public Admin.CYT369.Com.DAL.Domains.Department GetDepartmentByID(int id)
        {
            return this.GetOne<Admin.CYT369.Com.DAL.Domains.Department>(c => c.Id == id);
        }

        public IQueryable<Admin.CYT369.Com.DAL.Domains.Department> GetDepartmentByIDs(List<int> ids)
        {
            return this.Get<Admin.CYT369.Com.DAL.Domains.Department>(c => ids.Contains(c.Id));
        }

        public bool SaveDepartment(Admin.CYT369.Com.DAL.Domains.Department department)
        {
            if(department.Id > 0)
            {
                return this.Save<Admin.CYT369.Com.DAL.Domains.Department>(department, c => c.Id == department.Id);
            }
            else {
                return this.Save<Admin.CYT369.Com.DAL.Domains.Department>(department);
            }
        }

        public bool DeleteDepartment(int id)
        {
            using (var db = this.Ctx)
            {
                var list = new List<Admin.CYT369.Com.DAL.Domains.Department>();
                if (db.Set<Admin.CYT369.Com.DAL.Domains.Department>().Where(c => c.ParentID == id).Count() > 0)
                {
                    throw new Admin.CYT369.Com.Utility.Exceptions.DataExistException("任存在下级部门信息，不能删除当前部门");
                }

                if (db.Set<Admin.CYT369.Com.DAL.Domains.DepartmentUser>().Where(c => c.DepartmentID == id).Count() > 0)
                {
                    throw new Admin.CYT369.Com.Utility.Exceptions.DataExistException("该部门存在相关人员的信息，不能删除当前部门信息");
                }

                var item = db.Set<Admin.CYT369.Com.DAL.Domains.Department>().Where(c => c.Id == id).FirstOrDefault();
                if (item != null)
                {
                    db.Set<Admin.CYT369.Com.DAL.Domains.Department>().Remove(item);
                    db.SaveChanges();

                    return true;
                }
            }

            return false;
        }
        #endregion

        #region Users
        /// <summary>
        /// 用户与部门关系
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="isMain"></param>
        /// <returns></returns>
        public IEnumerable<Admin.CYT369.Com.DAL.Domains.DepartmentUser> GetUserDepartments(int userId, bool? isMain = null)
        {
            var query = base.Get<Admin.CYT369.Com.DAL.Domains.DepartmentUser>(c => c.UserID == userId);
            if (isMain.HasValue) {
                query = query.Where(c=>c.IsMain == isMain.Value);
            }

            return query.OrderByDescending(c=>c.IsMain).ToList();
        }

        /// <summary>
        /// 用户与部门关系
        /// </summary>
        /// <param name="departmentId"></param>
        /// <param name="isMain"></param>
        /// <returns></returns>
        public List<Admin.CYT369.Com.DAL.Domains.DepartmentUser> GetDepartmentUsers(int departmentId, bool? isMain = null)
        {
            var query = base.Get<Admin.CYT369.Com.DAL.Domains.DepartmentUser>(c => c.DepartmentID == departmentId);
            if (isMain.HasValue)
            {
                query = query.Where(c => c.IsMain == isMain.Value);
            }

            return query.OrderByDescending(c => c.IsMain).ToList();
        }

        public IEnumerable<Admin.CYT369.Com.DAL.Domains.PositionUser> GetUserPositions(int userId, bool? isMain = null)
        {
            var query = base.Get<Admin.CYT369.Com.DAL.Domains.PositionUser>(c => c.UserID == userId);
            if (isMain.HasValue)
            {
                query = query.Where(c => c.IsMain == isMain.Value);
            }

            return query.OrderByDescending(c=>c.IsMain).ToList();
        }

        #endregion

        #region Position
        public IQueryable<Admin.CYT369.Com.DAL.Domains.Position> GetPositions(int page, int rows, ref int total, int? organizationId = null, int? deptId = null, string positionName = null)
        {
            var items = base.Get<Admin.CYT369.Com.DAL.Domains.Position>();

            if (organizationId.HasValue)
            {
                items = items.Where(c=>c.OrgID == organizationId.Value);
            }

            if (deptId.HasValue)
            {
                items = items.Where(c=>c.DepartmentID == deptId.Value);
            }

            if (!string.IsNullOrEmpty(positionName))
            {
                items = items.Where(c => c.Name.Contains(positionName));
            }

            return this.Pagination(page, rows, ref total, items.Distinct(), c => c.Id);
        }

        public IQueryable<Admin.CYT369.Com.DAL.Domains.Position> GetPositions(int? orgId = null)
        {
            var query = this.Get<Admin.CYT369.Com.DAL.Domains.Position>();
            if (orgId.HasValue)
            {
                query = query.Where(c => c.OrgID == orgId.Value);
            }

            return query.OrderBy(c => c.Id);
        }

        public Admin.CYT369.Com.DAL.Domains.Position GetPositionByID(int id)
        {
            return this.GetOne<Admin.CYT369.Com.DAL.Domains.Position>(c => c.Id == id);
        }

        public IQueryable<Admin.CYT369.Com.DAL.Domains.Position> GetPositionByIDs(List<int> ids)
        {
            return this.Get<Admin.CYT369.Com.DAL.Domains.Position>(c => ids.Contains(c.Id));
        }

        public IQueryable<Admin.CYT369.Com.DAL.Domains.Position> GetPositionByDeptID(List<int> departmentIds, bool? enable)
        {
            IQueryable<Admin.CYT369.Com.DAL.Domains.Position> query = null;
            if (departmentIds != null)
            {
                if (departmentIds.Count > 0)
                {
                    if (departmentIds.Count == 1)
                    {
                        query = this.Get<Admin.CYT369.Com.DAL.Domains.Position>(c => c.DepartmentID == departmentIds[0]);
                    }
                    else
                    {
                        query = this.Get<Admin.CYT369.Com.DAL.Domains.Position>(c => departmentIds.Contains(c.DepartmentID));
                    }
                }
            }

            if (enable.HasValue)
            {
                query = query.Where(c=>c.Enable == enable.Value);
            }

            return query;
        }

        public bool SavePosition(Admin.CYT369.Com.DAL.Domains.Position position)
        {
            if (position.Id > 0)
            {
                return this.Save<Admin.CYT369.Com.DAL.Domains.Position>(position, c => c.Id == position.Id);
            }
            else
            {
                return this.Save<Admin.CYT369.Com.DAL.Domains.Position>(position);
            }
        }

        public bool DeletePosition(int id)
        {
            using (var db = this.Ctx)
            {
                var list = new List<Admin.CYT369.Com.DAL.Domains.Position>();
                if (db.Set<Admin.CYT369.Com.DAL.Domains.PositionUser>().Where(c => c.PositionID == id).Count() > 0)
                {
                    throw new Admin.CYT369.Com.Utility.Exceptions.DataExistException("该职务存在相关人员的信息，不能删除当前职务信息");
                }

                var item = db.Set<Admin.CYT369.Com.DAL.Domains.Position>().Where(c => c.Id == id).FirstOrDefault();
                if (item != null)
                {
                    db.Set<Admin.CYT369.Com.DAL.Domains.Position>().Remove(item);
                    db.SaveChanges();

                    return true;
                }
            }

            return false;
        }
        #endregion

    }
}
